package com.gonsin.ta.logic.process.quartz;

import com.gonsin.ta.logic.TA;
import com.gonsin.ta.logic.exceptions.TaException;
import com.gonsin.ta.logic.parse.condition.context.ChainContextImpl;
import com.gonsin.ta.logic.parse.condition.Executable;
import com.gonsin.ta.logic.parse.condition.context.ChainContextPo;
import com.gonsin.ta.logic.process.ExecutableSerializeHelper;
import com.gonsin.ta.logic.process.SignalCenter;
import com.gonsin.ta.logic.process.TaBus;
import com.gonsin.ta.logic.utils.JDKSerializationUtil;
import com.gonsin.ta.logic.utils.TaJson;
import lombok.extern.slf4j.Slf4j;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.util.CollectionUtils;

import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;

@Slf4j
public class TimeoutExecuteTask implements Job {

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {


        // 构建 ChainContext
        Map<String, Object> params = context.getMergedJobDataMap();
        byte[] contextBuffer = (byte[]) params.get("context");
        String timeoutTaskJson = (String) params.get("timeoutTask");
        String stackJson = (String) params.get("stack");
        String signalId = (String) params.get("signalId");
        SignalCenter center = (SignalCenter) params.get("signalCenter");

        List<Executable> executables = ExecutableSerializeHelper.createExecutableFromJson(timeoutTaskJson, stackJson, center);
        if(CollectionUtils.isEmpty(executables)){
            throw new TaException("TA - 反序列化失败，任务数量不应该为0");
        }
        ChainContextImpl chainContext = null;
        try {
            String json = new String(contextBuffer, StandardCharsets.UTF_8);
//            chainContext = TaJson.deSerialize(json, ChainContextImpl.class);
            ChainContextPo po = TaJson.deSerialize(json, ChainContextPo.class);
            chainContext = new ChainContextImpl(po);
            chainContext.setApplicationContext(TaBus.APPLICATION_CONTEXT);
        } catch (Exception e) {
            log.error(e.toString(), e);
            throw new TaException("反序列化context失败", e);
        }

        if(TA.LOG){
            TA.log().info("TA - 任务超时，触发执行【{}】的超时任务", chainContext.getChainId());
        }
        ChainContextImpl finalChainContext = chainContext;
        try {
            executables.forEach(e -> {
                try {
                    e.execute(finalChainContext);
                } catch (Exception ex) {
                    log.error(ex.toString(), ex);
                    throw new TaException("执行【{}】错误", e);
                }
            });
        } finally {
            center.deleteSignal(signalId);
        }
    }
}
